package cn.jesin.ssmss01.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.jesin.ssmss01.common.DefaultPassword;
import cn.jesin.ssmss01.entity.OtherAuth;
import cn.jesin.ssmss01.entity.User;
import cn.jesin.ssmss01.mapper.OtherAuthMapper;
import cn.jesin.ssmss01.mapper.UserMapper;
import cn.jesin.ssmss01.service.UserService;
import cn.jesin.ssmss01.utils.DataCheckUtil;
import cn.jesin.ssmss01.vo.OtherAuthInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @author 谷汉斌
 * @description
 * @createTime 2024/8/12 下午3:07
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OtherAuthMapper otherAuthMapper;

    /**
     * 绑定第三方账号
     *
     * @param otherAuthInfo 第三方账号信息
     * @return 是否绑定成功
     */
    @Override
    public boolean bind(OtherAuthInfo otherAuthInfo) {
        //判断合法性
        if (!DataCheckUtil.isValid(otherAuthInfo.oAuthOnlyId(), otherAuthInfo.getOthType())) {
            return false;
        }
        //判断该第三方账号是否已经被绑定
        if (otherAuthMapper.selectOtherAuthByoAuthTypeAndoAuthId(otherAuthInfo.getOthType(), otherAuthInfo.oAuthOnlyId()) != null) {
            return false;
        }
        String onlyId = otherAuthInfo.oAuthOnlyId();
        if (StrUtil.isNotBlank(onlyId)) {
            //获取当前登录的信息
            UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String info = principal.getUsername();
            //提取登录的唯一凭证和类型
            String loginKey = info.split(":")[0];
            String loginType = info.split(":")[1];
            if (StrUtil.isNotBlank(loginKey)) {
                User user = userMapper.selectUserByKey(Map.of(loginType, loginKey));
                //判断是否已经绑定第三方账号
                if (StrUtil.isNotBlank(user.getOauthInfo(otherAuthInfo.getOthType()))) {
                    //删除第三方登录授权信息
                    int id = user.parseOauth().get(otherAuthInfo.getOthType());
                    otherAuthMapper.deleteOtherAuthByPrimaryKey(id);
                }
                //绑定
                OtherAuth otherAuth = OtherAuth.builder()
                        .oAuthId(otherAuthInfo.oAuthOnlyId())
                        .oAuthType(otherAuthInfo.getOthType())
                        .username(user.getUsername())
                        .build();
                //更新用户信息
                if (otherAuthMapper.insertOtherAuth(otherAuth) == 1) {
                    user.updateOauthInfo(otherAuth.getOAuthType(), otherAuth.getOAuthId(), otherAuth.getId());
                    return userMapper.updateUser(user) == 1;
                }
            }
        }
        return false;
    }

    /**
     * 设置/更新密码
     *
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 是否更新成功
     */
    @Override
    public boolean updatePassword(String oldPassword, String newPassword) {
        //获取当前登录用户
        UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String info = principal.getUsername();
        String olnyId = info.split(":")[0];
        String auyhType = info.split(":")[1];
        if (StrUtil.isNotBlank(olnyId)) {
            User user = userMapper.selectUserByKey(Map.of(auyhType, olnyId));
            if (user == null) {
                return false;
            }
            //判断用户是否设置过密码
            boolean flag1 = new BCryptPasswordEncoder().matches(DefaultPassword.PASSWORD, user.getPassword());
            //判断旧密码是否正确
            boolean flag2 = new BCryptPasswordEncoder().matches(oldPassword, user.getPassword());
            if (!flag1 && !flag2) {
                return false;
            } else {
                return userMapper.updateUser(User.builder()
                        .id(user.getId())
                        .password(new BCryptPasswordEncoder().encode(newPassword))
                        .build()) == 1;
            }
        }
        return false;
    }
}
